home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Best of Select: Games 6
/
The Best of Select: Games 6.iso
/
slowdown
/
slowdown.asm
< prev
next >
Wrap
Assembly Source File
|
1986-04-05
|
5KB
|
177 lines
title SLOWDOWN.COM System Slowdown Routine 86.04.05a.dkg
name dev
page 60,132
;
TUNE_SPEED equ 224 ; tune to your CPU speed (approx Mhz*28)
;
CR equ 0dH
LF equ 0aH
;
;-----------------------------------------------------------------------+
; |
; PURPOSE: Provide a method to run an 8MHz 8086 based machine |
; at a comparable speed to the IBM for stupid programs |
; that assume a certain processor speed in their timing. |
; |
; FUNCTION: Intercept the tick interrupt and run a time-waster |
; loop for a user-settable delay before returning to the |
; running program. |
; |
; TO USE: From DOS, type SLOWDOWN [<percent>] where <percent> is |
; percentage of the CPU wasted. |
; |
; WRITTEN: 85.07.26 by David K. Goodwin |
; MODIFIED: 86.04.05.dkg, added intvec removal code |
; |
;-----------------------------------------------------------------------+
CODE SEGMENT
ASSUME CS:CODE,DS:CODE
; Program Segment Prefix
ORG 80H
NUM_CHARS db ? ; number of characters in argument
db ? ; leading blank
ARGTX db ? ; start of text (after leading blank)
;
; Program Area
;
ORG 100H
begin: jmp start
db 'Copyright 1986, David K. Goodwin'
;
; Interrupt Service Routine
; This routine will perform a time-waster loop every system clock tick
; 18 times per second. All memory references must use the CS segment prefix
; because that is the only segment setup by the INT call. I am using a
; method of Intercept routine ID somewhat like that done in CPMPLUS RSX's
; to prevent any conflict of this routine with any others that might
; intercept the interrupt I am using.
;
intvec dd ? ; next interrupt routine in sequence
loopcnt db ? ; number of 1% loops
db 'SLOWDOWN' ; Interrupt Intercept ID
tickint: pushf ; save flags
push ax ; save our useful reg
mov ah,cs:loopcnt ; load our loop counter
tick1: push cx
mov cx,TUNE_SPEED
tick2: loop tick2
pop cx
dec ah
jnz tick1
pop ax ; restore reg
popf ; restore flags
jmp cs:[intvec] ; go to next routine in chain
saveaddr label byte ; used as last location to keep in mem
;
; Start of main routine to process the command line.
;
start:
mov dx,offset signon
mov ah,9
int 21H
mov bx,offset argtx ; point to start of text argument
mov cl,num_chars ; set cx to number of chars in argument
xor ch,ch ; "
sub cx,1 ; discount char count for leading blank
ja parse_arg ; if so, handle w/termination routine
error: mov dx,offset errmsg ; if a problem give user help
error2: mov ah,9
int 21h
mov ax,4c01h ; terminate
int 21h
;
; Parse the numeric argument
; If the number is greater than 99 then we will error out with usage.
; If argument is zero, we will "unload" the interrupt service routine.
;
parse_arg: mov al,0 ; initialize char value to 0
mov dh,10d ; digit multiplier
getdigit: mov dl,[bx] ; get char code into dl
sub dl,'0' ; convert digit code to value
jb error ; error checks
cmp dl,'9' ;
ja error ; must be a digit
mul dh ; mult. char value (in al) by 10
add al,dl ; add digit value to char value
inc bx ; skip to next char
dec cx ; "
jnz getdigit ; exit if at end of text (cx = 0)
cmp al,99 ; if over 99, error
ja error
mov loopcnt,al ; save our loop counter
mov ah,35h ; get old tick interrupt
mov al,1ch
int 21h
sub bx,8 ; check for interrupt already alive
mov ax,word ptr es:[bx] ; get first 2 chars
cmp ax,'LS' ; if SL, already exists
je exists ; do mod of routine
cmp loopcnt,0 ; if zero, jump to removal routine
jnz chgint
mov dx,offset notresmsg
jmp error2
chgint: add bx,8 ; get intvec back to normal
mov word ptr intvec,bx
mov word ptr intvec+2,es
mov ah,25h ; save new int vector
mov al,1ch
mov dx,offset tickint
int 21h
;
; Done with loading and initialize
; Print out a message to say we did it and leave
;
complete: mov dx,offset byemsg ; point to completion message
mov ah,9 ; code for dos display string function
int 21h ; display message via dos function call
mov ah,31h ; keep program in memory for int vector
mov al,0
mov dx,offset saveaddr
int 21h ; bye bye
notresmsg: db 'SLOWDOWN not resident$'
byemsg: db 'SLOWDOWN loaded$'
exists: mov al,loopcnt ; get specified loopcnt
cmp al,0 ; if we are removing
jz rmvint
dec bx ; point int copy of loopcnt
mov byte ptr es:[bx],al ; save percentile
mov dx,offset existmsg
jmp goodret
existmsg: db 'SLOWDOWN started at new value$'
rmvint: sub bx,5 ; point to old intvec
push ds
cli
lds dx,es:[bx] ; get old int vector
mov ah,25h ; restore old int vector
mov al,1ch
int 21h
sti
pop ds
mov dx,offset rmvmsg
jmp goodret
rmvmsg: db 'SLOWDOWN removed$'
goodret: mov ah,9
int 21h
mov ax,4c00h ; terminate
int 21h
signon: db 'SLOWDOWN v1.1a 86.04.05.dkg',CR,LF,'$'
errmsg: db CR,LF
db 'usage: a>SLOWDOWN <percent>',CR,LF
db ' where <percent> is between 0 and 99',CR,LF
db ' if <percent> is 0, remove slowdown interrupt',CR,LF
db '$'
code ends
end begin